﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Unity;

namespace DistributedServices.Core.InstanceProvider
{
    /// <summary>
    /// Service behavior base  for adding Unity instance provider in each
    /// endpoint dispatcher
    /// </summary>
    public class UnityInstanceProviderServiceBehaviorBase : Attribute, IServiceBehavior
    {
        #region Members
        IUnityContainer _container;
        #endregion


        #region ctor
        public UnityInstanceProviderServiceBehaviorBase(IUnityContainer container)
        {
            _container = container;

        }
        #endregion




        #region IServiceBehavior Members


        /// <summary>
        /// <see cref="System.ServiceModel.Description.IServiceBehavior"/>
        /// </summary>
        /// <param name="serviceDescription">
        /// <see cref="System.ServiceModel.Description.IServiceBehavior"/>
        /// </param>
        ///<param name="serviceHostBase">
        /// <see cref="System.ServiceModel.Description.IServiceBehavior"/>
        /// </param>
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
            {
                if (dispatcher != null) // add new instance provider for each end point dispatcher
                {
                    dispatcher.Endpoints.ToList().ForEach(endpoint =>
                    {
                        endpoint.DispatchRuntime.InstanceProvider = new UnityInstanceProvider(serviceDescription.ServiceType, _container);
                    });
                }
            }

        }

        /// <summary>
        /// <see cref="System.ServiceModel.Description.IServiceBehavior"/>
        /// </summary>
        /// <param name="serviceDescription">
        /// <see cref="System.ServiceModel.Description.IServiceBehavior"/>
        /// </param>
        ///<param name="serviceHostBase">
        /// <see cref="System.ServiceModel.Description.IServiceBehavior"/>
        /// </param>
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }


        /// <summary>
        /// <see cref="System.ServiceModel.Description.IServiceBehavior"/>
        /// </summary>
        /// <param name="serviceDescription">
        /// <see cref="System.ServiceModel.Description.IServiceBehavior"/>
        /// </param>
        ///<param name="serviceHostBase">
        /// <see cref="System.ServiceModel.Description.IServiceBehavior"/>
        /// </param>
        ///<param name="endpoints">
        /// <see cref="System.ServiceModel.Description.IServiceBehavior"/>
        /// </param>
        ///<param name="bindingParameters">
        /// <see cref="System.ServiceModel.Description.IServiceBehavior"/>
        /// </param>
        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
        }

        #endregion
    }
}
